﻿using Newtonsoft.Json;
using Opc.Ua;
using Opc.Ua.Client;
using SHRIS.MIS.Common.Enum.APIExternal;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.Service.LinePlantService;
using SHRIS.MIS.Service.OpcService;
using SHRIS.MIS.Service.RabbitService;
using ShrisCommunicationCore.OpcUa;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SHRIS.MIS.Service.Device
{
    public class MainPlc_12 : BasicDevice
    {

        private readonly IEnumerable<OpcDataSourceEntity> _opcDataSourceEntities;

        public MainPlc_12(DeviceEntity deviceEntity,
            WorkshopCommunicationService workshopCommunicationService,
            IEnumerable<OpcDataSourceEntity> opcDataSourceEntities) 
            : base(deviceEntity, workshopCommunicationService)
        {
            _opcDataSourceEntities = opcDataSourceEntities;
            CheckOutDataType();
        }


        private void CheckOutDataType()
        {
            //对所有OPC 数据类型进行校验，如果不对记入LOG

        }



   



        public override void InitalDevice()
        {
            //创建opc 订阅

            //找出该通道下的订阅数据，dataAction==4 为订阅
            var subscriptionDatas = _opcDataSourceEntities.Where(i => i.DataAction == 4);

            //找出订阅数据的服务器列表
            var serverIds = subscriptionDatas.Select(i => i.ServerId).Distinct().ToList();

            if (serverIds.Count() == 1)
            {
                _workshopCommunicationService.CreateOpcSubscription(subscriptionDatas, DataHandler);
            }


            //用deviceCode作为订阅组名字
            //var subscriptionName = _deviceEntity.DeviceCode;

        }


        private void DataHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                //Console.WriteLine(notification.Value.StatusCode.ToString());

                if (notification != null)
                {
                    Guid dataId = new Guid();
                    bool isId = Guid.TryParse(monitoredItem.DisplayName, out dataId);
                    if (isId && (!dataId.IsGuidNullOrEmpty()))
                    {
                        var dataSource = _opcDataSourceEntities.Where(i => i.Id == dataId).First();
                        switch (dataSource.DataName)
                        {
                            case "OrderControlMode":
                                {
                                    OrderControlMode = (bool)notification.Value.Value;
                                    break;
                                }
                            case "ManualStatus":
                                {
                                    ManualStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AutoStatus":
                                {
                                    AutoStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "FirstpieceStatus":
                                {
                                    FirstpieceStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AutoReadyStatus":
                                {
                                    AutoReadyStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AutoRunStatus":
                                {
                                    AutoRunStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AutoStopStatus":
                                {
                                    AutoStopStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "AllRestartStatus":
                                {
                                    AllRestartStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "SuspendStatus":
                                {
                                    SuspendStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "BypassStatus_01":
                                {
                                    BypassStatus_01 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "BypassStatus_02":
                                {
                                    BypassStatus_02 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "BypassStatus_03":
                                {
                                    BypassStatus_03 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO_01":
                                {
                                    EMO_01 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO_02":
                                {
                                    EMO_02 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO_03":
                                {
                                    EMO_03 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready_01":
                                {
                                    Ready_01 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready_02":
                                {
                                    Ready_02 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready_03":
                                {
                                    Ready_03 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "End_01":
                                {
                                    End_01 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "End_02":
                                {
                                    End_02 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "End_03":
                                {
                                    End_03 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasWorkpiece_01":
                                {
                                    HasWorkpiece_01 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasWorkpiece_02":
                                {
                                    HasWorkpiece_02 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasWorkpiece_03":
                                {
                                    HasWorkpiece_03 = (bool)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource_01":
                                {
                                    WorkpieceSource_01 = (short)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource_02":
                                {
                                    WorkpieceSource_02 = (short)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource_03":
                                {
                                    WorkpieceSource_03 = (short)notification.Value.Value;
                                    break;
                                }
                            case "Dayoff":
                                {
                                    DayOff = (bool)notification.Value.Value;
                                    break;
                                }
                            case "DayoffStatus":
                                {
                                    DayOffStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "TEST4":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    Alarm1 = new BitArray(b);
                                    break;
                                }

                            default:
                                {
                                    break;
                                }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region 设备参数

        private BitArray alarm1;
        /// <summary>
        /// PLC报警1
        /// </summary>
        public BitArray Alarm1
        {
            get
            {
                return alarm1;
            }
            set
            {
                BitArray previewVlaue = alarm1;
                alarm1 = value;
                OnPropertyChanged("Alarm1", previewVlaue, alarm1);
            }
        }

        private BitArray alarm2;
        /// <summary>
        /// PLC报警2
        /// </summary>
        public BitArray Alarm2
        {
            get
            {
                return alarm2;
            }
            set
            {
                BitArray previewVlaue = alarm2;
                alarm2 = value;
                OnPropertyChanged("Alarm2", previewVlaue, alarm2);
            }
        }

        private BitArray alarm3;
        /// <summary>
        /// PLC报警3
        /// </summary>
        public BitArray Alarm3
        {
            get
            {
                return alarm3;
            }
            set
            {
                BitArray previewVlaue = alarm3;
                alarm3 = value;
                OnPropertyChanged("Alarm3", previewVlaue, alarm3);
            }
        }

        private BitArray alarm4;
        /// <summary>
        /// PLC报警4
        /// </summary>
        public BitArray Alarm4
        {
            get
            {
                return alarm4;
            }
            set
            {
                BitArray previewVlaue = alarm4;
                alarm4 = value;
                OnPropertyChanged("Alarm4", previewVlaue, alarm4);
            }
        }

        private BitArray alarm5;
        /// <summary>
        /// PLC报警5
        /// </summary>
        public BitArray Alarm5
        {
            get
            {
                return alarm5;
            }
            set
            {
                BitArray previewVlaue = alarm5;
                alarm5 = value;
                OnPropertyChanged("Alarm5", previewVlaue, alarm5);
            }
        }

        private bool _orderControlMode;
        /// <summary>
        /// 订单控制模式 true=远程（启用数据跟踪） false=本地（不跟踪数据）
        /// </summary>
        public bool OrderControlMode
        {
            get
            {
                return _orderControlMode;
            }
            set
            {
                bool previewVlaue = _orderControlMode;
                _orderControlMode = value;
                OnPropertyChanged("OrderControlMode", previewVlaue, _orderControlMode);
            }
        }


        private bool _manualStatus;
        /// <summary>
        /// 手动模式
        /// </summary>
        public bool ManualStatus
        {
            get
            {
                return _manualStatus;
            }
            set
            {
                bool previewVlaue = _manualStatus;
                _manualStatus = value;
                OnPropertyChanged("ManualStatus", previewVlaue, _manualStatus);
            }
        }

        private bool _autoStatus;
        /// <summary>
        /// 自动模式
        /// </summary>
        public bool AutoStatus
        {
            get
            {
                return _autoStatus;
            }
            set
            {
                bool previewValue = _autoStatus;
                _autoStatus = value;
                OnPropertyChanged("AutoStatus", previewValue, _autoStatus);
            }
        }

        private bool _firstpieceStatus;
        /// <summary>
        /// 首件模式
        /// </summary>
        public bool FirstpieceStatus
        {
            get
            {
                return _firstpieceStatus;
            }
            set
            {
                bool previewValue = _firstpieceStatus;
                _firstpieceStatus = value;
                OnPropertyChanged("FirstpieceStatus", previewValue, _firstpieceStatus);
            }
        }

        private bool _autoReadyStatus;
        /// <summary>
        /// 准备模式
        /// </summary>
        public bool AutoReadyStatus
        {
            get
            {
                return _autoReadyStatus;
            }
            set
            {
                bool previewValue = _autoReadyStatus;
                _autoReadyStatus = value;
                OnPropertyChanged("AutoReadyStatus", previewValue, _autoReadyStatus);
            }
        }



        private bool _autoRunStatus;
        /// <summary>
        /// 启动模式
        /// </summary>
        public bool AutoRunStatus
        {
            get
            {
                return _autoRunStatus;
            }
            set
            {
                bool previewValue = _autoRunStatus;
                _autoRunStatus = value;
                OnPropertyChanged("AutoRunStatus", previewValue, _autoRunStatus);
            }
        }

        private bool _autoStopStatus;
        /// <summary>
        /// 停止模式
        /// </summary>
        public bool AutoStopStatus
        {
            get
            {
                return _autoStopStatus;
            }
            set
            {
                bool previewValue = _autoStopStatus;
                _autoStopStatus = value;
                OnPropertyChanged("AutoStopStatus", previewValue, _autoStopStatus);
            }
        }

        private bool _allRestartStatus;
        /// <summary>
        /// 全线重新开始
        /// </summary>
        public bool AllRestartStatus
        {
            get
            {
                return _allRestartStatus;
            }
            set
            {
                bool previewValue = _allRestartStatus;
                _allRestartStatus = value;
                OnPropertyChanged("AllRestartStatus", previewValue, _allRestartStatus);
            }
        }


        private bool _suspendStatus;
        /// <summary>
        /// 运行暂停
        /// </summary>
        public bool SuspendStatus
        {
            get
            {
                return _suspendStatus;
            }
            set
            {
                bool previewValue = _suspendStatus;
                _suspendStatus = value;
                OnPropertyChanged("SuspendStatus", previewValue, _suspendStatus);
            }
        }

        private bool bypassStatus_01;
        public bool BypassStatus_01
        {
            get
            {
                return bypassStatus_01;
            }
            set
            {
                bool previewValue = bypassStatus_01;
                bypassStatus_01 = value;
                OnPropertyChanged("BypassStatus_01", previewValue, bypassStatus_01);
            }
        }

        private bool bypassStatus_02;
        public bool BypassStatus_02
        {
            get
            {
                return bypassStatus_02;
            }
            set
            {
                bool previewValue = bypassStatus_02;
                bypassStatus_02 = value;
                OnPropertyChanged("BypassStatus_02", previewValue, bypassStatus_02);
            }
        }

        private bool bypassStatus_03;
        public bool BypassStatus_03
        {
            get
            {
                return bypassStatus_03;
            }
            set
            {
                bool previewValue = bypassStatus_03;
                bypassStatus_03 = value;
                OnPropertyChanged("BypassStatus_03", previewValue, bypassStatus_03);
            }
        }

        private bool eMO_01;
        public bool EMO_01
        {
            get
            {
                return eMO_01;
            }
            set
            {
                bool previewValue = eMO_01;
                eMO_01 = value;
                OnPropertyChanged("EMO_01", previewValue, eMO_01);
            }
        }

        private bool eMO_02;
        public bool EMO_02
        {
            get
            {
                return eMO_02;
            }
            set
            {
                bool previewValue = eMO_02;
                eMO_02 = value;
                OnPropertyChanged("EMO_02", previewValue, eMO_02);
            }
        }

        private bool eMO_03;
        public bool EMO_03
        {
            get
            {
                return eMO_03;
            }
            set
            {
                bool previewValue = eMO_03;
                eMO_03 = value;
                OnPropertyChanged("EMO_03", previewValue, eMO_03);
            }
        }

        private bool ready_01;
        public bool Ready_01
        {
            get
            {
                return ready_01;
            }
            set
            {
                bool previewValue = ready_01;
                ready_01 = value;
                OnPropertyChanged("Ready_01", previewValue, ready_01);
            }
        }

        private bool ready_02;
        public bool Ready_02
        {
            get
            {
                return ready_02;
            }
            set
            {
                bool previewValue = ready_02;
                ready_02 = value;
                OnPropertyChanged("Ready_02", previewValue, ready_02);
            }
        }

        private bool ready_03;
        public bool Ready_03
        {
            get
            {
                return ready_03;
            }
            set
            {
                bool previewValue = ready_03;
                ready_03 = value;
                OnPropertyChanged("Ready_03", previewValue, ready_03);
            }
        }

        private bool end_01;
        public bool End_01
        {
            get
            {
                return end_01;
            }
            set
            {
                bool previewValue = end_01;
                end_01 = value;
                OnPropertyChanged("End_01", previewValue, end_01);
            }
        }

        private bool end_02;
        public bool End_02
        {
            get
            {
                return end_02;
            }
            set
            {
                bool previewValue = end_02;
                end_02 = value;
                OnPropertyChanged("End_02", previewValue, end_02);
            }
        }

        private bool end_03;
        public bool End_03
        {
            get
            {
                return end_03;
            }
            set
            {
                bool previewValue = end_03;
                end_03 = value;
                OnPropertyChanged("End_03", previewValue, end_03);
            }
        }

        private bool hasWorkpiece_01;
        public bool HasWorkpiece_01
        {
            get
            {
                return hasWorkpiece_01;
            }
            set
            {
                bool previewValue = hasWorkpiece_01;
                hasWorkpiece_01 = value;
                OnPropertyChanged("HasWorkpiece_01", previewValue, hasWorkpiece_01);
            }
        }

        private bool hasWorkpiece_02;
        public bool HasWorkpiece_02
        {
            get
            {
                return hasWorkpiece_02;
            }
            set
            {
                bool previewValue = hasWorkpiece_02;
                hasWorkpiece_02 = value;
                OnPropertyChanged("HasWorkpiece_02", previewValue, hasWorkpiece_02);
            }
        }

        private bool hasWorkpiece_03;
        public bool HasWorkpiece_03
        {
            get
            {
                return hasWorkpiece_03;
            }
            set
            {
                bool previewValue = hasWorkpiece_03;
                hasWorkpiece_03 = value;
                OnPropertyChanged("HasWorkpiece_03", previewValue, hasWorkpiece_03);
            }
        }

        private short workpieceSource_01;
        public short WorkpieceSource_01
        {
            get
            {
                return workpieceSource_01;
            }
            set
            {
                short previewValue = workpieceSource_01;
                workpieceSource_01 = value;
                OnPropertyChanged("WorkpieceSource_01", previewValue, workpieceSource_01);
            }
        }

        private short workpieceSource_02;
        public short WorkpieceSource_02
        {
            get
            {
                return workpieceSource_02;
            }
            set
            {
                short previewValue = workpieceSource_02;
                workpieceSource_02 = value;
                OnPropertyChanged("WorkpieceSource_02", previewValue, workpieceSource_02);
            }
        }

        private short workpieceSource_03;
        public short WorkpieceSource_03
        {
            get
            {
                return workpieceSource_03;
            }
            set
            {
                short previewValue = workpieceSource_03;
                workpieceSource_03 = value;
                OnPropertyChanged("WorkpieceSource_03", previewValue, workpieceSource_03);
            }
        }

        private bool dayOff;
        public bool DayOff
        {
            get
            {
                return dayOff;
            }
            set
            {
                bool previewValue = dayOff;
                dayOff = value;
                OnPropertyChanged("DayOff", previewValue, dayOff);
            }
        }

        private bool dayOffStatus;
        public bool DayOffStatus
        {
            get
            {
                return dayOffStatus;
            }
            set
            {
                bool previewValue = dayOffStatus;
                dayOffStatus = value;
                OnPropertyChanged("DayOffStatus", previewValue, dayOffStatus);
            }
        }


        #endregion

    }
}
